package com.heima.comment.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.heima.comment.dto.*;
import com.heima.comment.entity.*;
import com.heima.comment.feign.ArticleFeign;
import com.heima.comment.feign.MediaFeign;
import com.heima.comment.feign.UserFeign;
import com.heima.comment.service.ICommentService;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.dto.PageResponseResult;
import com.heima.common.dto.ResponseResult;
import com.heima.common.dto.User;
import com.heima.common.enums.AppHttpCodeEnum;
import com.heima.common.util.AppThreadLocalUtil;
import com.heima.common.util.MediaThreadLocalUtil;
import com.mongodb.client.result.DeleteResult;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

@Service
public class CommentService implements ICommentService {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Override
    public ResponseResult list(CommentDto dto) {
        Long articleId = dto.getArticleId();
        Criteria criteria = new Criteria();
        criteria.and("entryId").is(dto.getArticleId());
        Query query = new Query();
        query.skip((dto.getPage()-1)*dto.getSize()).limit(dto.getSize());
        query.addCriteria(criteria);
        query.with(Sort.by(Sort.Order.desc("createdTime")));
        List<ApComment> apComments = mongoTemplate.find(query, ApComment.class);
        if(apComments==null){
            return PageResponseResult.okResult();
        }
        //List<String> ids = CollUtil.getFieldValues(apComments, "id", String.class);
        //ArrayList comments = new ArrayList<>();
//        Criteria criteria1 = new Criteria();
//        criteria1.and("entryId").is(dto.getArticleId());
//        criteria1.and("entryId").is(dto.getArticleId()).and("commentId").in(ids);
//        List<ApCommentReply> apCommentReplies = mongoTemplate.find(Query.query(criteria1), ApCommentReply.class);
        //comments.add(apCommentReplies);
        //comments.add(apComments);
        ArrayList arrayList = new ArrayList();
        for (ApComment apComment : apComments) {
            String id = apComment.getId();
            Criteria criteria1 = new Criteria();
            criteria1.and("entryId").is(dto.getArticleId());
            criteria1.and("commentId").is(id);
            List<ApCommentReply> apCommentReplies = mongoTemplate.find(Query.query(criteria1).with(Sort.by(Sort.Order.desc("createdTime"))), ApCommentReply.class);
            Map map = new HashMap();
            map.put("apComments",apComment);
            map.put("apCommentRepays",apCommentReplies);
            arrayList.add(map);
        }

        return new PageResponseResult(dto.getPage(),dto.getSize(),Long.valueOf(apComments.size()),arrayList);
    }

    @Autowired
    private MediaFeign mediaFeign;
    @Override
    public ResponseResult repay(RepayDto dto) {
        String commentId = dto.getCommentId();
        ApCommentReply apCommentReply = new ApCommentReply();
        User user = MediaThreadLocalUtil.get();
        //todo 调用wm服务查询ap_user_id
        Integer id= user.getUserId();
        String name = user.getName();
        WmUser wmUser = mediaFeign.findWmUser(id);
        Integer userId = wmUser.getApUserId();
        apCommentReply.setAuthorId(userId);
        apCommentReply.setAuthorName(name);
        apCommentReply.setCommentId(commentId);
        apCommentReply.setContent(dto.getContent());
        apCommentReply.setCreatedTime(new Date());
        Criteria criteria = new Criteria();
        criteria.and("id").is(commentId);
        ApComment one = mongoTemplate.findOne(Query.query(criteria), ApComment.class);
        apCommentReply.setEntryId(one.getEntryId());
        //todo 查询user
        //apCommentReply.setImage();
        ApCommentReply save = mongoTemplate.save(apCommentReply);
        return ResponseResult.okResult(save);
    }

    @Override
    public ResponseResult delete(String id) {
        Criteria criteria = new Criteria();
        criteria.and("id").is(id);
        DeleteResult remove = mongoTemplate.remove(Query.query(criteria), ApComment.class);
        return ResponseResult.okResult(remove);
    }

    @Override
    public ResponseResult deleteRepay(String id) {
        Criteria criteria = new Criteria();
        criteria.and("id").is(id);
        ApCommentReply one = mongoTemplate.findOne(Query.query(criteria), ApCommentReply.class);
        DeleteResult remove = mongoTemplate.remove(Query.query(criteria), ApCommentReply.class);

        Criteria criteria1 = new Criteria();
        criteria1.and("id").is(one.getCommentId());
        ApComment comment = mongoTemplate.findOne(Query.query(criteria1), ApComment.class);
        Integer reply = comment.getReply();
        comment.setReply(reply-1);
        mongoTemplate.save(comment);
        return ResponseResult.okResult(remove);
    }

    @Override
    public ResponseResult like(LikeDto dto) {
        User user = MediaThreadLocalUtil.get();
        //todo 调用wm服务查询ap_user_id
        Integer id = user.getUserId();
        String name = user.getName();
        WmUser wmUser = mediaFeign.findWmUser(id);
        Integer userId = wmUser.getApUserId();
        String commentId = dto.getCommentId();
        Integer operation = dto.getOperation();
        Criteria criteria = new Criteria();
        criteria.and("commentId").is(commentId).and("authorId").is(userId);
        Like one = mongoTemplate.findOne(Query.query(criteria), Like.class);

        Criteria criteria1 = new Criteria();
        criteria1.and("id").is(commentId);
        ApComment comment = mongoTemplate.findOne(Query.query(criteria1), ApComment.class);
        Long likes = comment.getLikes();

        if(one!=null){
            if(one.getOperation()!= operation){
                Update update = new Update();
                update.set("operation",operation);
                mongoTemplate.updateFirst(Query.query(criteria),update,"ap_comment_like");

                if(operation == 0){
                    comment.setLikes(likes+1);
                    mongoTemplate.save(comment);
                }else {
                    comment.setLikes(likes-1);
                    mongoTemplate.save(comment);
                }
            }else {
                return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST);
            }
        }else {
            Like like = new Like();
            like.setOperation(operation);
            like.setAuthorId(userId);
            like.setCommentId(commentId);
            mongoTemplate.save(like);
            comment.setLikes(likes+1);
            mongoTemplate.save(comment);
        }
        ApComment apComment = mongoTemplate.findOne(Query.query(criteria1), ApComment.class);
        return ResponseResult.okResult(apComment.getLikes());
    }



    @Autowired
    private GreenTextScan textScan;

    @Autowired
    private ArticleFeign articleFeign;

    @Autowired
    private UserFeign userFeign;

    // 发布评论
    @Override
    public ResponseResult save(CommentSaveDto dto) {

        // 获取用户id
        User user = AppThreadLocalUtil.get();

        // 判断用户登录方式
        if (user == null){

            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        // 获取评论内容
        String content = dto.getContent();
        Long articleId = dto.getArticleId();
        ApArticle article = articleFeign.findArticle(articleId);
        if(!article.getIsComment()){
            return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPERATOR_AUTH);
        }

        // 判断
        if (StringUtils.isEmpty(content)){

            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (content.length() > 140){

            return ResponseResult.errorResult(402,"评论内容不能超过140字");
        }

        ApComment apComment = new ApComment();

        try {
            // 评论审核
            Map map = textScan.greenTextScan(content);

            // 判断结果
            String suggestion = (String) map.get("suggestion");

            switch (suggestion) {
                case "pass":
                    // 审核通过

                    /*// 1.根据文章id查询文章
                    System.err.println(dto.getArticleId());
                    ResponseResult<ApArticle> result = articleFeign.select(dto.getArticleId());*/

                    // 1.根据用户id查询用户信息

                   /* // 判断
                    if (result.getCode().equals(AppHttpCodeEnum.SUCCESS.getCode())){*/

                       /* ApArticle apArticle = result.getData();

                        // 获取作者信息
                        Integer authorId = apArticle.getAuthorId();
                        String authorName = apArticle.getAuthorName();*/

                    // 2.根据userId获取用户信息
                    ResponseResult<ApUser> userResponseResult = userFeign.selectUser(user.getUserId());
                    // 判断
                    if (userResponseResult.getCode().equals(AppHttpCodeEnum.SUCCESS.getCode())){

                        ApUser apUser = userResponseResult.getData();

                        String name = apUser.getName();
                        String image = apUser.getImage();

                        // 3.封装数据
                        apComment.setAuthorId(user.getUserId());
                        apComment.setAuthorName(name);
                        apComment.setEntryId(dto.getArticleId());
                        apComment.setType(0);
                        apComment.setContent(content);
                        apComment.setImage(image);
                        apComment.setCreatedTime(new Date());

                        // 4.保存
                        mongoTemplate.save(apComment);

                        // 更新文章表的评论数
                        articleFeign.update(dto.getArticleId());
                    }

                    break;
                case "block":
                    // 审核不通过
                    return ResponseResult.errorResult(402,"审核失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ResponseResult.okResult(apComment);
    }


    // 查询评论列表
    @Override
    public ResponseResult load(CommentDto dto) {

        // 判断
        if (dto == null){

            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }



        // 获取请求参数
        Long articleId = dto.getArticleId();// 文章id
        Date minDate = dto.getMinDate();// 最小时间
        Long page = dto.getPage();
        Integer size = dto.getSize();


        // 指定查询条件
        Criteria criteria = Criteria.where("entryId").is(articleId).and("createdTime").lt(minDate);

        Query query = Query.query(criteria).skip((page - 1) * size).limit(size).with(Sort.by(Sort.Order.desc("createdTime")));

        // 查询
        List<ApComment> commentList = mongoTemplate.find(query, ApComment.class);

        List<ApComment> apComments = new ArrayList<>();

        // 判断是否对评论点赞
        // 循环遍历
        for (ApComment apComment : commentList) {

            // 获取评论id
            String commentId = apComment.getId();

            // 获取用户id
            Integer userId = AppThreadLocalUtil.get().getUserId();
            if (userId != null){

                // 指定查询条件
                Criteria criteria1 = Criteria.where("authorId").is(userId).and("commentId").is(new ObjectId(commentId));

                // 查询
                ApCommentLike commentLike = mongoTemplate.findOne(Query.query(criteria1), ApCommentLike.class);

                // 判断
                if (commentLike != null && commentLike.getOperation() == 0){

                    apComment.setOperation(0);

                }

                // System.err.println(apComment);

                apComments.add(apComment);
            }
        }



        return ResponseResult.okResult(apComments);
    }

    // 评论点赞
    @Override
    public ResponseResult likes(CommentLikeDto dto) {

        // 获取用户id
        Integer userId = AppThreadLocalUtil.get().getUserId();

        if (userId == null){

            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        if (dto == null){

            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 获取评论Id
        String commentId = dto.getCommentId();
        Short operation = dto.getOperation();

        // 查询是否已经点赞
        // 1.指定查询条件
        Criteria criteria1 = Criteria.where("authorId").is(userId).and("commentId").is(commentId);

        // 2.查询
        ApCommentLike commentLike = mongoTemplate.findOne(Query.query(criteria1), ApCommentLike.class);

        // 3.判断

        if (commentLike == null && dto.getOperation() == 0){

            // 保存点赞数据
            ApCommentLike apCommentLike = new ApCommentLike();
            apCommentLike.setAuthorId(userId);
            apCommentLike.setCommentId(commentId);
            apCommentLike.setOperation(0);
            mongoTemplate.save(apCommentLike);

            // 更新评论表点赞数量
            updateCommentLikes(commentId, operation);

        }


        if (commentLike != null && !commentLike.getOperation().toString().equals(operation.toString())){

            // 更新点赞表
            Update update = new Update();
            update.set("operation",dto.getOperation());
            mongoTemplate.updateFirst(Query.query(criteria1),update,ApCommentLike.class);

            // 更新评论表点赞数量
            updateCommentLikes(commentId, operation);

        }

        return ResponseResult.okResult();
    }

    // 更新评论表点赞数量
    private void updateCommentLikes(String commentId, Short operation) {

        // 更新评论表数据
        ApComment apComment = mongoTemplate.findById(new ObjectId(commentId), ApComment.class);
        Long likes = apComment.getLikes();
        if (operation == 0){
            likes = ++likes;
        }else if (operation == 1){
            likes = --likes;
        }
        apComment.setLikes(likes);
        mongoTemplate.save(apComment);
    }
}
